Chapter 8

Adding Date and Time Functions


CONTENTS

Times and dates were invented for client-side processing; the ancient scholars and monks must have had Web browsers in the back of their minds-forward-thinking guys!

Every client computer contains several variables that tell the computer what time it is and what the date is. In DOS, it's as easy as c:>date. (For those of you too young to remember DOS, it means disk operating system, something we used regularly in the old days.)

If it's so easy to learn the computer's time and date variables, why did I spend hours writing a program that acquires the domain of the client requesting a Web page (such as .bh for Bahrain), dips into a database to find out how many hours they are ahead or behind GMT, adds this to the time at the server, and then decides whether it is morning, afternoon, or evening where the client is? That kind of program was necessary because until the advent of client-side scripting, you had no way to access the date and time variables on the client computer. HTML just doesn't have a tag for time or date.

Dates and times are ideal for creating semi-personalized and variable Web pages, and they include some of the variables you can actually obtain from the client machine. (No doubt some lobby group will make a proposal to ban this because it impinges on privacy.) You could even take this concept further and make an almost completely different page based on the time of day. Get your imagination around that one!

Accessing the Client's Date and Time Variables

First, take a look at how you access the time and date variables that are held in the client's computer. As with everything in VBScript, the function names are easy and logical. To grab the date and use it in your script, you write the following:

myDate = Date()

To access the client's time, use

myLawyer = Time()

To get both date and time in one variable, use

myVariable = Now()

The functions do not take any variables and therefore the parentheses, which must be there because these are functions, remain empty.

What do these three variables return? It depends upon your window settings. All three functions are formatted based upon the date, time, and international settings of your window system. The easiest way to see what they return and how to use them is to try them.

Listing 8.1 contains a quick HTML page that contains three buttons: one for displaying the time, one for the date, and one for both. You can find it on the CD-ROM.


Listing 8.1. The datetime.htm code.
<HTML>
 <HEAD>
  <SCRIPT LANGUAGE="vbscript">
   Sub DoTime_OnClick
    Document.Form1.Output.Value = Time()
   End Sub

   Sub DoDate_OnClick
    Document.Form1.Output.Value = Date()
   End Sub

   Sub DoNow_OnClick
    Document.Form1.Output.Value = Now()
   End Sub
  </SCRIPT>
 </HEAD>

<BODY BGCOLOR="white">
<CENTER>
<FORM NAME="Form1">
<INPUT TYPE="button" NAME="DoTime" Value="Show the current Time"><P>
<INPUT TYPE="button" NAME="DoDate" Value="Show the current Date"><P>
<INPUT TYPE="button" NAME="DoNow" Value="Show both Date and Time"><P>
<INPUT TYPE="text" NAME="Output">
</FORM>
</CENTER>
</BODY>
</HTML>

Figure 8.1 shows what Listing 8.1 looks like with the browser.

Figure 8.1 : The date and time example.

Note
The computer stores the complete date and time as a double-precision number. The whole number part represents the date from 1/1/100 to 31/12/9999. 1/1/1900 is represented by the number 2. The fractional part of the number represents the time. 12:00 noon is .5.

Welcoming Users in Their Own Time Zones

How do you usually welcome someone to a Web site? "Hello" and "Welcome to my Web site" are very general greetings. They have to be general if you don't know what part of the day the user is in. This is the age of the interactive personalized Web page, right? Shouldn't you say, "Good morning," "Good afternoon," and "Good evening"?

As I said at the beginning of this chapter, it is possible to write a server-side script that roughly determines the time where the user is, but it is not recommended. VBScript gives you more time and date functionality than a Rolex watch, so put away your sundial and look at the sample welcome page in Figure 8.2.

Figure 8.2 : Welcoming your Web page visitor.

How is it done? This welcome page uses the Hour() function within VBScript. Unlike the Now() and Time() functions in Windows 95 that return a 12-hour clock format, Hour() always returns the hour in 24-hour format. You need only to check whether the hour is before 12 (morning), between 12 and 18 (afternoon), or after 18 (evening). The result is printed on the Web page using the document's write method.

Creating the Welcome Page HTML Template

Using your favorite HTML editor or Notepad, create the following HTML Web page template and save it as timeofday.htm:

<HTML>
<HEAD>
 <TITLE>My Welcome Page</TITLE>
 <SCRIPT LANGUAGE="vbscript">
  <!--TIME OF DAY FUncTION GOES HERE -->
 </SCRIPT>
</HEAD>
<BODY BGCOLOR="White">
<FONT FACE="arial" SIZE=2>
<CENTER>
<H3>

<!-- CUSTOM HEADING GOES HERE -->

<BR>
Welcome to my Home Page
</H3>
</CENTER>
<P>
<BLOCKQUOTE>
This fine
<!--CUSTOM TIME OF DAY GOES HERE-->
I have lots for you to see and experience, etc. etc.
</BODY>
</HTML>

Creating the Time of Day Function

Now edit the file, adding the following function to the <SCRIPT> tags within the <HEAD> section:

Function TimeOfDay()
   If Hour(Now()) < 12 Then
      TimeOfDay = "Morning"
   End if

   If Hour(Now()) =>12 AND Hour(Now()) < 18 Then
      TimeOfDay = "Afternoon"
   End if

   If Hour(Now()) => 18 Then
      TimeOfDay = "Evening"
   End if
End Function

The TimeOfDay custom function uses the Now() function to pass the current time to the Hour() function. As a result, the Hour() function returns the hour at the time the script runs.

Comparisons on the hour value determine whether it is morning, afternoon, or evening, according to the definitions mentioned earlier. You could optimize the previous code by copying the hour value into a variable first and then using that variable within the If.....Then comparisons.

Now you need some code within the body of the HTML file that calls the TimeOfDay function when necessary.

Adding the Function Calls to the HTML Page

In the comment section marked Custom heading goes here, type the following short script:

<SCRIPT LANGUAGE="vbscript">
Document.Write "Good " & TimeOfDay()
</SCRIPT>

This script contains no function or subdefinition, which means that the script executes as the file is loaded into the browser. In other words, as the browser reaches this section, it executes the script code.

This code calls the Write method, passing to it the word "Good" and the result of the TimeOfDay() function-either Morning, Afternoon, or Evening. The Write method prints onto the HTML page at the next available position.

Having taken care of the heading, you need to add the function call to place the time of day into the paragraph below the headings. Type the following code into the HTML page at the point that says Custom Time of Day Goes Here:

<SCRIPT LANGUAGE="vbscript">
Document.Write LCase(TimeOfDay())
</SCRIPT>

Again, this code executes as the file loads. Notice that this time, to make the word fit in with the rest of the paragraph, the script calls the LCase function to convert the result of TimeOfDay to all lowercase characters.

Take a look at some other related functions that you can use to dissect the date.

Rearranging the Date

In Chapter 6 "Checking Form Data," you saw how to use the IsDate() function to verify that an entry could be translated to a real date. You also saw that this function checks only that the entry is within the limitations of the date format used by the client machine and could be meaningless to you after the date is received at the server. For example, 96.3.1 is a valid date in some countries but could give your database palpitations.

The solution is to first check that the entry is a valid date and then reformat the date to your liking. VBScript has three built-in functions to help you do this:

Day()
Month()
Year()

The full syntax is

variable = Day(datevariable)
variable = Month(datevariable)
variable = Year(datevariable)

Regardless of where the user's window format placed the year, month, and day, these three functions return the correct digit. It's a simple task for you to rearrange these digits within a string in the order of your choosing, whether it's the British style of dd/mm/yy, the American style of mm/dd/yy, or any other combination, for that matter.

Creating the HTML Template for the Date Rearranger

First, create the HTML template with the following code:

<HTML>
<HEAD>
<TITLE>Date Re-Arrangement</TITLE>
<SCRIPT LANGUAGE="vbscript">
<!-- Date rearrangement script goes here -->
</SCRIPT>
</HEAD>
<BODY BGCOLOR="white">
<CENTER>

<FORM NAME="Form1">
Enter a date &nbsp;
<INPUT TYPE="text" NAME="InputDate">
<P>
<INPUT TYPE="button" NAME="ChangeDate" VALUE="Change Date Format">
<P>
<INPUT TYPE="text" NAME="OutputDate">
</FORM>

</CENTER>
</BODY>
</HTML>

When it's entered, save the file as mixdate.htm.

Adding the Date Rearrangement Function

In the following code that does all the work, I added line numbers to make it easier to follow the description; however, don't add these line numbers to your script:

1:Function MixDate(StartDate)
2:  Dim strSeparator
3:  Dim strTheMonth
4:  Dim strTheYear
5:  Dim strTheDay
6:  Dim strFinalDate

7:   strSeparator = "/"

8:   strTheMonth = Month(StartDate)
9:   strTheYear = Year(StartDate)
10:   strTheDay = Day(StartDate)

11:   strFinalDate = strTheDay & strSeparator & _
12:                  strTheMonth & strSeparator & _
13:                  strTheYear

14:   MixDate = strFinalDate

15: End Function

Line 1 is the function definition that specifies the name of this custom function and also specifies that it expects to receive a variable when it is called. In this case, the variable is the date value entered by the user.

Lines 2 through 6 define several variables that are used locally during the execution of the function.

Line 7 assigns a forward slash (/) character to the strSeparator variable, which separates the day, month, and year in the final format. If you want to receive dates with other types of separators (for example, dashes -), simply edit this line.

The next three lines-8, 9, and 10-are where the work really starts. The variables you created at the beginning of the function are assigned their respective values by calling the built-in Day(), Month(), and Year() functions, which operate on the date value passed in at the start.

Note
VBScript has similar functions for splitting the time variables-Hour(), Minute(), and Second()-which can be used in exactly the same way as Day(), Month(), and Year().

You've now split the date into its three main constituents and defined your own separator for the date. All that remains is sticking the date back together in the order of your choice, using sticky tape, staples, or whatever comes to hand. In this case, lines 11, 12, and 13 concatenate the string into a day, month, year format. You could just as easily edit this to be year, month, day.

Finally, line 14 copies the reformed date to the return value of the function itself. When the function completes in line 15 and execution is passed back to the code that called it, the reformed date is returned.

You need to add some code that calls the custom function when it is needed.

Adding the Function Call to the Date Rearrangement Page

For this example, the function call comes from the event handler for the ChangeDate button. Type the following code into the <SCRIPT> tags just above the custom function:

 Sub ChangeDate_OnClick
  If IsDate(Document.Form1.InputDate.Value) Then
   Document.Form1.OutputDate.Value = MixDate(Document.Form1.InputDate.Value)
  Else
   Alert "Not a valid date format"
  End If
 End Sub

The first job is to check that the value entered into the text box can in fact be treated as a date. If it can't, a warning message displays and nothing happens.

If the user entered a valid date in the text box, the value is passed to the MixDate function. The value that is returned from the MixDate function is copied into the OutputDate text box.

You can now validate date values and also return them to the server in whatever format you need for further processing. All of this processing is done quickly and efficiently at the client, as shown in Figure 8.3.

Figure 8.3 : The date rearrangement function at work.

As you can see from this sample page, December 12 96 is a valid date, but I doubt it would fit into anyone's date formatting system.

Calculating with Dates and Times

What's 1st July 1996 plus 231 days? Or 47 days prior to the 23rd February 1997? Unless you're a mathematical genius, you probably need to count days on a calendar. Actually, that's what computers are for-and also what the next example is for.

In this example, you build a date calculator, a fairly straightforward application in which you enter a date and then choose whether you want to add or subtract x number of days, months, or years to or from the original date. Have fun entering your birth date and finding out when you'll turn 10,000 days old.

Creating the Date Calculator HTML Template

The form contains a text box in which you enter a date. Under the form is a drop-down selection list containing a choice of the operator to use-either plus or minus. Next to this list is a text box in which you enter the date difference and another selection list containing the time period-days, years, or months.

The button starts the whole thing and a text box shows the result-simple! Use the following code for your HTML page:

<HTML>
<HEAD>
<TITLE>Date Calculator</TITLE>
<SCRIPT LANGUAGE="vbscript">

</SCRIPT>
</HEAD>

<BODY BGCOLOR="white">
<FONT FACE="arial" SIZE=2>
<CENTER>

<H2>Date Calculator</H2>
<FORM NAME="Form1">
Enter a Date &nbsp;
<INPUT TYPE="text" NAME="InputDate">
<P>

<SELECT NAME="operation">
<OPTION>Add
<OPTION>Take Away
</SELECT>

<INPUT TYPE="text" NAME="Number" SIZE=6>

<SELECT NAME="period">
<OPTION>Days
<OPTION>Months
<OPTION>Years
</SELECT>

<P>
<INPUT TYPE="button" Name="Calculate" VALUE="Calculate Now">
<P>
Result &nbsp;
<INPUT TYPE="text" NAME="Result">
</FORM>
</CENTER>

</BODY>
<HTML>

After you build your template, save it as datecalc.htm and test it in the browser. Yes, I know that it didn't do anything. It's time to add the calculation script.

Adding the Date Calculation Script

Take this one step at a time. First, add the following code under the <SCRIPT> tag:

Sub Calculate_OnClick

 If Not IsDate(Document.Form1.InputDate.Value) Then
  Alert "This is not a valid date"
  Exit Sub
 End If

As you know by now, this subroutine is an event handler for the Calculate command button. This first part of the script ensures that the date you entered is a valid date format. Now, add the second stage:

StartDate = Document.Form1.InputDate.Value
StartMonth = Month(StartDate)
StartDay = Day(StartDate)
StartYear = Year(StartDate)

You might recognize this section from the date rearrangement example you saw earlier in this chapter; it's pretty much identical. You split the date into its constituent parts. Continue your work by adding the following code:

If Document.Form1.operation.SelectedIndex = 1 Then
 Difference = 0 - CInt(Document.Form1.Number.Value)
Else
 Difference = CInt(Document.Form1.Number.Value)
End if

You might remember this section (or one like it) from an earlier chapter. Here, you learn which of the options the user (or you) chose from the list. Remember, the first item on the list is always index 0. You know that you placed "Take Away" in the second slot on the list, which is index number 1. If the selectedIndex property is 1, you perform a subtraction. The easiest way to write this section is to always perform an addition. If you really want an addition, use a positive number; if you want to subtract, use a negative number. You change the difference to negative if the user selected Take Away. Now enter the next section:

Select Case Document.Form1.period.SelectedIndex
 Case 0
  EndDate = DateSerial(StartYear, StartMonth, StartDay + Difference)
 Case 1
  EndDate = DateSerial(StartYear, StartMonth + Difference, StartDay)
 Case 2
  EndDate = DateSerial(StartYear + Difference, StartMonth, StartDay)
End Select

This section performs the actual mathematics and also sticks back together the constituent parts of the date. The Select block saves you from typing umpteen different If...Thens. You can learn more about Select...Case in Chapter 9 "Making Your Program Flow."

This section uses the second selection list-day, month, or year-as its condition. As you saw in the last section, if the user wants to take a number of days away from the starting date, the difference is negative. DateSerial puts the date back together in its correct form, adjusting months and years accordingly so that you don't end up with the 125th of March. Add the following section to the end of your code:

 Document.Form1.Result.Value = EndDate

End Sub

Copy the result into the result text box and end the subroutine. As your final task, check back through your code. Listing 8.2 shows the complete source code.


Listing 8.2. The datecalc.htm code.
<HTML>
<HEAD>
<TITLE>Date Calculator</TITLE>
<SCRIPT LANGUAGE="vbscript">
 Sub Calculate_OnClick

 If Not IsDate(Document.Form1.InputDate.Value) Then
  Alert "This is not a valid date"
  Exit Sub
 End if

  StartDate = Document.Form1.InputDate.Value
  StartMonth = Month(StartDate)
  StartDay = Day(StartDate)
  StartYear = Year(StartDate)

  If Document.Form1.operation.SelectedIndex = 1 Then
   Difference = 0 - CInt(Document.Form1.Number.Value)
  Else
   Difference = CInt(Document.Form1.Number.Value)
  End if

  Select Case Document.Form1.period.SelectedIndex
   Case 0
    EndDate = DateSerial(StartYear, StartMonth, StartDay + Difference)
   Case 1
    EndDate = DateSerial(StartYear, StartMonth + Difference, StartDay)
   Case 2
    EndDate = DateSerial(StartYear + Difference, StartMonth, StartDay)
  End Select

  Document.Form1.Result.Value = EndDate

 End Sub

</SCRIPT>
</HEAD>

<BODY BGCOLOR="white">
<FONT FACE="arial" SIZE=2>
<CENTER>

<H2>Date Calculator</H2>
<FORM NAME="Form1">
Enter a Date &nbsp;
<INPUT TYPE="text" NAME="InputDate">
<P>
<SELECT NAME="operation">
<OPTION>Add
<OPTION>Take Away
</SELECT>
<INPUT TYPE="text" NAME="Number" SIZE=6>
<SELECT NAME="period">
<OPTION>Days
<OPTION>Months
<OPTION>Years
</SELECT>
<P>
<INPUT TYPE="button" Name="Calculate" VALUE="Calculate Now">
<P>
Result &nbsp;
<INPUT TYPE="text" NAME="Result">
</FORM>
</CENTER>

</BODY>
<HTML>

Save your file and run it with the browser. It should perform as shown in Figure 8.4.

Figure 8.4 : The date calculator sample.

Using the Date Last Modified Variable

As you surf around the Net, you often see pages that tell you when the page you are looking at was last modified. You might even have some of these yourself. A last modified date is as useful for you, the webmaster, as it is for the site visitor. But you have to hard code the last modified date into your HTML page, and therefore you have to remember to manually update this HTML coded date when you update the page. If you forget to change the date, its usefulness is lost. So, wouldn't it be nice to have a last modified date that updates itself automatically when you amend the page? Well, now you can do this by simply adding this short piece of VBScript to any HTML page and even adding it to your HTML page template. It requires almost no thought and certainly no maintenance on your part.

The document object carries with it the date you last modified the document. It's easy to acquire the document's LastModified property and display it to the world:

Document.Write Document.LastModified

Listing 8.3 shows a sample page that uses the LastModified property.


Listing 8.3. The lastmod.htm code.
<HTML>
<HEAD>
<TITLE>Last Updated</TITLE>
</HEAD>
<BODY BGCOLOR="white">
<!--

YOUR PAGE GOES HERE

-->

<FONT FACE="arial" SIZE=1>
<B>
<CENTER>
<SCRIPT LANGUAGE="vbscript">
<!--
  Document.Write "This page was last modified on "
  Document.Write Document.LastModified
-->
</SCRIPT>
</CENTER>
</B>

</BODY>
</HTML>

Figure 8.5 shows what Listing 8.3 looks like in the browser.

Figure 8.5 : A maintenance-free "last modified" message.

Place the script at the bottom of your HTML page, and without any further work on your part, this code always shows the day, date, and time that the document was last saved, which is useful for both you and the visitor.

Automating What's New

The next example is a really neat way of using client-side processing and VBScript. It saves you time and automatically maintains your page. When you add some feature or modify part of your site, you often stick in a "new" graphic to alert users to the fact that something has changed. Unless you regularly maintain the page, this new graphic can remain there long after its "sell-by" date. We've all seen pages that denote something as new when in fact we saw the same thing several months previously. We'd never do that on our own Web sites-would we?

The following sample application displays the new graphic based on the date at the client machine. All you have to do is supply a sell-by date. After this date is reached, the graphic no longer appears.

Creating the What's New Template

First, create the following HTML template document:

<HTML>
<HEAD>
 <TITLE>My NEW Welcome Page</TITLE>

 <SCRIPT LANGUAGE="vbscript">

 </SCRIPT>
</HEAD>

<BODY BGCOLOR="White">
<FONT FACE="arial" SIZE=3>

<CENTER>
<H3>
Welcome to my Home Page
</H3>
<P>

<A HREF="">My Links Page</A><P>

<A HREF="">Photos from my last vacation</A><P>

<A HREF="">My Resum&eacute;</A>

</CENTER>
</BODY>
</HTML>

Save the template as whatsnew.htm, and you're ready to attack the scripting.

Adding the Subroutine to Automatically Insert a "New" Graphic

Place the following subroutine inside the <SCRIPT> tags in the <HEAD> section:

Sub Sellby(LastDate)
   If DateValue(Now()) < DateValue(LastDate) Then
     Document.Write "<IMG SRC=" & Chr(34) & "new.gif" & Chr(34) & 
	" ALIGN=MIDDLE>"
   End If
End Sub

The Sellby subroutine takes one variable, a sell-by date-which is basically the date at which you decide the item is no longer new. The DateValue function, which you saw in the previous section, is used here to convert whatever is brought into the subroutine to a date and to place both the value returned by Now() and the LastDate on a level playing field so that you can compare one with the other.

If the date at the browser is less than (earlier than) the LastDate variable, you are still within the new period, so you want to show the new.gif graphic.

The Document.Write method writes a line of code to the document defining an image tag. Because the string passed to Document.Write must be enclosed in quotation marks, you cannot use quotes for the image filename. This line builds in the quotes (ASCII code 34) programmatically using the Chr() function. The program actually sees this line as <IMG SRC="new.gif" ALIGN=MIDDLE>.

Adding the Calls to the Subroutine

Now you can display a new graphic based upon the date at the browser, but you need a way to call this routine into action. Before each hyperlink, insert the following code:

<SCRIPT LANGUAGE="vbscript">
  SellBy ("12 Sept 96")
</SCRIPT>

You don't have to stick to a certain date format; just remember that the format you use must be capable of conversion to a date by DateValue(). Here's the completed hyperlink section, showing several variations of the date format:

<SCRIPT LANGUAGE="vbscript">
  SellBy ("12 Sept 96")
</SCRIPT>
<A HREF="">My Links Page</A><P>

<SCRIPT LANGUAGE="vbscript">
  SellBy ("August 14")
</SCRIPT>
<A HREF="">Photos from my last vacation</A><P>

<SCRIPT LANGUAGE="vbscript">
  SellBy ("10/12/96")
</SCRIPT>
<A HREF="">My Resum&eacute;</A>

Figure 8.6 shows what your file looks like when you fire it up in the browser.

Figure 8.6 : The "New!" graphics added automatically--or not.

Workshop Wrap-Up

In this chapter, you saw how to use the built-in date and time functionality of VBScript and the browser with the document's LastModified property.

You discovered how easy it is to grab the client's date and time variables and manipulate them. You also saw how quickly you can include the VBScript built-in functions to perform calculations on the time and date variables and reformat any date or time.

Next Steps

Now that you've seen how to use the built-in date and time functionality of VBScript, you can produce all sorts of neat client-side applications. See the following chapters to add further client-side time and date power:

Q&A

Q:
Visual Basic has many date and time functions and features that save a lot of time and trouble. Are they going to be included in VBScript at some point?
A:
Keep a look out for the next release of VBScript, which could be out by the time you read this. It is rumored that additional date and time functions will be included in the next release, although most of the Visual Basic date and time functions can be replicated using the methods shown in this chapter.
Q:
How do I save the date when a user last visited my site?
A:
The only way that you can store data on the client machine is via the cookie file. For more information on cookies, see Chapter 19.